using System;
using System.Text;
using System.Security.Cryptography;
using System.Reflection;
using System.Collections.Generic;
using System.Linq;


namespace Classes.Bases
{
    /// <summary>
    /// Defines the members inherited by all Entity objects.
    /// </summary>
    [System.Runtime.Serialization.DataContract]
    public abstract class Entity
    {
        #region " Hash Stuff "

        /// <summary>
        /// Stores an integer to be used as a "salt" in the hash generation algorithm.
        /// </summary>
        private int prop_HashSalt = 8675309;

        /// <summary>
        /// Gets or Sets the salt value used by <see cref="MakeHash" /> to generate a hash value.
        /// </summary>
        /// <value>
        /// The integer used in hash generation.
        /// </value>
        internal int HashSalt
        {
            private get
            {
                return prop_HashSalt;
            }
            set
            {
                prop_HashSalt = value;
            }
        }

        /// <summary>
        /// Generates a hash for the given string value using the SHA1 algorithm and returns a
        /// base64-encoded string. 
        /// </summary>
        /// <param name="inputstring">
        /// Value to be hashed; <c>null</c> and <c>string.Empty</c> are acceptable.
        /// </param>
        /// <returns>
        /// A hash value formatted as a base64-encoded string.
        /// </returns>
        /// <remarks>
        /// <para>Takes the value given in <paramref name="inputstring"/> plus the value in <see cref="HashSalt"/>, stores them in a <c>byte</c> array, and computes
        /// a hash value out of them, using <see cref="System.Security.Cryptography.SHA1Managed"/>. The salt bytes are then added to the hash, and the combined 
        /// number converted to a base64 string that is returned.</para>
        /// </remarks>
        protected string MakeHash(string inputstring)
        {

            byte[] saltBytes = BitConverter.GetBytes(HashSalt);

            // Convert plain text into a byte array.
            byte[] plainTextBytes = Encoding.UTF8.GetBytes(inputstring);

            // Allocate array, which will hold plain text and salt.
            byte[] plainTextWithSaltBytes =
                new byte[plainTextBytes.Length + saltBytes.Length];

            // Copy plain text bytes into resulting array.
            for (int i = 0; i < plainTextBytes.Length; i++)
                plainTextWithSaltBytes[i] = plainTextBytes[i];

            // Append salt bytes to the resulting array.
            for (int i = 0; i < saltBytes.Length; i++)
                plainTextWithSaltBytes[plainTextBytes.Length + i] = saltBytes[i];

            // Create a SHA1 hashing algorithm class.
            HashAlgorithm hash = new SHA1Managed();

            // Compute hash value of our plain text with appended salt.
            byte[] hashBytes = hash.ComputeHash(plainTextWithSaltBytes);

            // Create array which will hold hash and original salt bytes.
            byte[] hashWithSaltBytes = new byte[hashBytes.Length + saltBytes.Length];

            // Copy hash bytes into resulting array.
            for (int i = 0; i < hashBytes.Length; i++)
                hashWithSaltBytes[i] = hashBytes[i];

            // Append salt bytes to the result.
            for (int i = 0; i < saltBytes.Length; i++)
                hashWithSaltBytes[hashBytes.Length + i] = saltBytes[i];

            // Convert result into a base64-encoded string.
            string hashValue = Convert.ToBase64String(hashWithSaltBytes);

            // Return the result.
            return hashValue;

        }

        #endregion

   
    }

}